<template>
	<div class="menu">
		<el-row :gutter="10">
			<el-col :sm="7" :xs="24">
				<div class="app-container">
					<div class="filter-container">
						<el-input placeholder="名称" @keyup.enter.native="search" class="filter-item search-item" clearable v-model="label" />
						<el-tooltip content="新增/删除时，请先勾选菜单" effect="dark" placement="right">
							<el-dropdown class="filter-item" trigger="click" style="margin: 10px 0;">
								<el-button>
									更多 <i class="el-icon-arrow-down" />
								</el-button>
								<el-dropdown-menu slot="dropdown">
									<el-dropdown-item @click.native="add">添加</el-dropdown-item>
									<el-dropdown-item @click.native="deleteMenu">删除</el-dropdown-item>
								</el-dropdown-menu>
							</el-dropdown>
						</el-tooltip>
					</div>
					<commonTree :tree-data="menuTree" @nodeClick="nodeClick" ref="menuTree">
						<template slot-scope="treeNode">
							<span class="tree-icon"><i :class="treeNode.data.icon ? treeNode.data.icon : 'el-icon-document'" /></span>
							<span class="tree-icon"><el-badge :type="treeNode.data.isLocked ? 'danger' : 'success'" class="status-item" is-dot /></span>
						</template>
					</commonTree>
				</div>
			</el-col>
			<el-col :sm="7" :xs="24">
				<el-card class="box-card">
					<div class="clearfix" slot="header">
						<span>{{ menu.id === '' ? '添加' : '编辑' }}</span>
					</div>
					<div>
						<el-form :model="menu" :rules="rules" label-position="right" label-width="100px" ref="form">
							<el-form-item label="上级ID" prop="parentId">
								<el-tooltip content="值为0时表示顶级节点" effect="dark" placement="right"><el-input readonly v-model="menu.parentId" /></el-tooltip>
							</el-form-item>
							<el-form-item label="名称" prop="label"><el-input v-model="menu.label" /></el-form-item>
							<el-form-item label="路由URI" prop="menuUrl"><el-input v-model="menu.menuUrl" /></el-form-item>
							<el-form-item label="组件" prop="component">
								<el-input v-model="menu.component" />
								<span>{{ menuComponent }}</span>
							</el-form-item>
							<el-form-item label="图标" prop="icon">
								<el-input v-model="menu.icon"><el-button @click="chooseIcons" icon="el-icon-brush" slot="append" /></el-input>
							</el-form-item>
							<el-form-item label="状态" prop="isLocked"><el-switch active-text="禁用" inactive-text="启用" v-model="menu.isLocked" /></el-form-item>
							<el-form-item label="排序" prop="sort"><el-input-number :max="100" :min="0" @change="handleNumChange" v-model="menu.sort" /></el-form-item>
						</el-form>
					</div>
				</el-card>
				<el-card class="box-card" style="margin-top: -2rem;">
					<el-row>
						<el-col :span="24" style="text-align: right">
							<el-button @click="submit" plain type="primary">{{ menu.id === '' ? '添加' : '修改' }}</el-button>
						</el-col>
					</el-row>
				</el-card>
			</el-col>
			<el-col :sm="10" :xs="24">
				<el-card class="box-card">
					<div class="app-container">
						<div class="filter-container">
							<el-dropdown class="filter-item" trigger="click" style="margin: 10px 0;">
								<el-button>
									更多<i class="el-icon-arrow-down" />
								</el-button>
								<el-dropdown-menu slot="dropdown">
									<el-dropdown-item :disabled="!menu.id" @click.native="resourceAdd">添加</el-dropdown-item>
									<el-dropdown-item @click.native="resourceBatchDelete">编辑</el-dropdown-item>
								</el-dropdown-menu>
							</el-dropdown>
						</div>
						<el-table
							:data="resourceTableData"
							:key="resourceTableKey"
							@selection-change="onResourceSelectChange"
							@sort-change="resourceSortChange"
							@filter-change="resourceFilterChange"
							border fit ref="resourceTable"
							style="width: 100%;"
							v-loading="resourceLoading">
							<el-table-column align="center" type="selection" width="40px" />
							<el-table-column label="编码" :show-overflow-tooltip="true" align="center" prop="authorizeCode">
								<template slot-scope="scope">
									<span>{{ scope.row.authorizeCode }}</span>
								</template>
							</el-table-column>
							<el-table-column label="名称" :show-overflow-tooltip="true" align="center" prop="actionName">
								<template slot-scope="scope">
									<span>{{ scope.row.actionName }}</span>
								</template>
							</el-table-column>
							<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="80px">
								<template slot-scope="{ row }">
									<i @click="resourceEdit(row)" class="el-icon-edit table-operation" style="color: #2db7f5;margin-right: 20px;" />
									<i @click="resourceSingleDelete(row)" class="el-icon-delete table-operation" style="color: #f50;" />
								</template>
							</el-table-column>
						</el-table>
					</div>
				</el-card>
			</el-col>
		</el-row>
		<Icons :dialog-visible="iconVisible" @choose="chooseIcon" @close="iconVisible = false" />
		<resource-edit :dialog-visible="dialog.isVisible" :type="dialog.type" @close="resourceEditClose" @success="resourceEditSuccess" ref="resourceEdit" />
	</div>
</template>
<script>
import commonTree from '@/components/common/CommonTree.vue';
import Icons from './Icons';
import ResourceEdit from './Edit';
import Pagination from '@/components/Pagination';
import { initQueryParams } from '@/utils/common';
import { get, postJson, postXform } from '@/utils/request.js';

export default {
	name: 'MenuManage',
	components: { Icons, commonTree, Pagination, ResourceEdit },
	data() {
		return {
			dialog: {
				isVisible: false,
				type: 'add'
			},
			preview: {
				isVisible: false,
				context: ''
			},
			iconVisible: false,
			menuTree: [],
			label: '',
			menuName: '',
			menu: this.initMenu(),
			resourceQueryParams: initQueryParams({
				model: {
					menuId: null
				}
			}),
			resourceTableKey: 0,
			resourceLoading: false,
			resourceSelection: [],
			resourceTableData: [],
			rules: {
				menuName: [{ required: true, message: '不能为空', trigger: 'blur' }, { min: 1, max: 255, message: '请输入1-255个字符', trigger: 'blur' }],
				menuUrl: [{ max: 255, message: '请输入1-255个字符', trigger: 'blur' }, { required: true, message: '不能为空', trigger: 'blur' }]
			},
			isAddRootMenu: false
		};
	},
	computed: {
		menuComponent() {
			let comp = '';
			if (this.menu.component) {
				comp = `组件路径：src/views/${this.menu.component}.vue`;
			}
			return comp;
		}
	},
	watch: {},
	mounted() {
		this.initMenuTree();
	},
	methods: {
		initMenuTree() {
			get('menu/getApplicationMenuTree', {}).then(res => {
				this.menuTree = res.data.data;
				for (let i = 0; i < this.menuTree.length; i++) {
					this.initAppId(this.menuTree[i], this.menuTree[i].id);
				}
			});
		},
		initAppId(menuTree, appId) {
			menuTree.appId = appId;
			if (menuTree.children) {
				menuTree.children.forEach(element => {
					this.initAppId(element, appId);
				});
			}
		},
		initMenu() {
			return {
				id: '',
				menuName: '',
				code: '',
				menuUrl: '',
				component: '',
				isLocked: false,
				sort: '',
				parentId: 0,
				icon: ''
			};
		},
		nodeClick(data) {
			this.menu = { ...data };
			console.log(this.menu);
			this.$refs.form.clearValidate();
			this.resourceSearch();
		},
		handleNumChange(val) {
			this.menu.sort = val;
		},
		chooseIcons() {
			this.iconVisible = true;
		},
		chooseIcon(icon) {
			this.menu.icon = icon;
			this.iconVisible = false;
		},
		submit() {
			this.$refs.form.validate(valid => {
				if (valid) {
					this.menu.createTime = this.menu.updateTime = null;
					if (this.menu.id) {
						this.update();
					} else {
						this.save();
					}
				} else {
					return false;
				}
			});
		},
		save() {
			let param = { ...this.menu };
			if (this.isAddRootMenu) {
				param.appId = this.menu.parentId;
				param.parentId = null;
			}
			param.menuName = this.menu.label;
			postXform('/menu/addMenu', param).then(res => {
				this.$message({
					message: '添加成功',
					type: 'success'
				});
				this.reset();
			});
		},
		update() {
			let param = { ...this.menu };
			param.menuName = this.menu.label;
			postXform('/menu/updateMenu', param).then(res => {
				this.$message({
					message: '修改成功',
					type: 'success'
				});
				this.reset();
			});
		},
		reset() {
			this.initMenuTree();
			this.menuName = '';
			this.resetForm();
		},
		search() {
			this.$refs.menuTree.$refs.treeRef.filter(this.menuName);
		},
		add() {
			this.resetForm();
			const checked = this.$refs.menuTree.$refs.treeRef.getCheckedKeys();
			if (checked.length > 1) {
				this.$message({
					message: '只能选择一个',
					type: 'warning'
				});
			} else if (checked.length > 0) {
				this.menu.parentId = checked[0];
				let nodes = this.$refs.menuTree.$refs.treeRef.getCheckedNodes();
				if (nodes[0].label == '后台管理系统' || nodes[0].label == '小程序') {
					this.isAddRootMenu = true;
				} else {
					this.isAddRootMenu = false;
				}
				this.menu.appId = nodes[0].appId;
			} else {
				this.$message({
					message: '必须选择一个节点',
					type: 'warning'
				});
			}
			this.resourceQueryParams.model.menuId = null;
			this.resourceTableData = [];
		},
		deleteMenu() {
			const checked = this.$refs.menuTree.$refs.treeRef.getCheckedKeys();
			if (checked.length === 0) {
				this.$message({
					message: '请选择一个',
					type: 'warning'
				});
			} else {
				this.$confirm('选中节点及其子结点将被永久删除, 是否继续？', '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				})
					.then(() => {
						postXform('/menu/deleteMenu', { ids: checked }).then(res => {
							this.$message({
								message: '删除成功',
								type: 'success'
							});
							this.reset();
							this.resourceQueryParams.model.menuId = null;
							this.resourceReset();
						});
					})
					.catch(() => {
						this.$refs.menuTree.$refs.treeRef.setCheckedKeys([]);
					});
			}
		},
		resetForm() {
			this.$refs.form.clearValidate();
			this.$refs.form.resetFields();
			this.menu = this.initMenu();
		},
		resourceAdd() {
			this.dialog.type = 'add';
			this.dialog.isVisible = true;
			this.$refs.resourceEdit.setResource({
				menuId: this.menu.id
			});
		},
		resourceEdit(row) {
			this.dialog.type = 'edit';
			this.dialog.isVisible = true;
			row.menuId = this.menu.id;
			this.$refs.resourceEdit.setResource(row);
		},
		resourceSingleDelete(row) {
			this.$refs.resourceTable.clearSelection();
			this.$refs.resourceTable.toggleRowSelection(row, true);
			this.resourceBatchDelete();
		},
		resourceBatchDelete() {
			if (!this.resourceSelection.length) {
				this.$message({
					message: '请先选择需要操作的数据',
					type: 'warning'
				});
				return;
			}
			this.$confirm('选中节点及其子结点将被永久删除, 是否继续？', '提示', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning'
			}).then(() => {
				const ids = this.resourceSelection.map(item => item.id);
				postXform('/menu/deleteAction', { ids: ids }).then(res => {
					this.$message({
						message: '删除成功',
						type: 'success'
					});
					this.resourceReset(ids);
				});
			});
		},
		resourceReset(ids) {
			this.$refs.resourceTable.clearSort();
			this.$refs.resourceTable.clearFilter();
			this.resourceTableData.forEach((item, index) => {
				for (let i = 0; i < ids.length; i++) {
					if (item.id == ids[i]) {
						this.resourceTableData.splice(index, 1);
						break;
					}
				}
			});
		},
		resourceSearch() {
			this.resourceTableData = this.menu.actions;
		},
		resourceSortChange(val) {
			this.resourceQueryParams.sort = val.prop;
			this.resourceQueryParams.order = val.order;
			if (this.resourceQueryParams.sort) {
				this.resourceSearch();
			}
		},
		resourceFilterChange(filters) {
			for (const key in filters) {
				if (key.includes('.')) {
					const val = {};
					val[key.split('.')[1]] = filters[key][0];
					this.resourceQueryParams.model[key.split('.')[0]] = val;
				} else {
					this.resourceQueryParams.model[key] = filters[key][0];
				}
			}
			this.resourceSearch();
		},
		onResourceSelectChange(selection) {
			this.resourceSelection = selection;
		},
		resourceEditClose() {
			this.dialog.isVisible = false;
		},
		resourceEditSuccess(resource) {
			let flag = false;
			this.dialog.isVisible = false;
			this.menu.actions.forEach(item => {
				if (item.id == resource.id) {
					item.actionName = resource.actionName;
					item.authorizeCode = resource.authorizeCode;
					flag = true;
					return;
				}
			});
			if (!flag) {
				this.menu.actions.push(resource);
			}
		}
	}
};
</script>
<style lang="less" scoped>
</style>
